package com.xnew.aes;

import com.xnew.bean.common.SysUserInfo;
import com.xnew.operator.bean.AcctOperatorLog;
import com.xnew.operator.service.AcctOperatorLogService;
import com.xnew.utils.RedisUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import com.alibaba.fastjson.JSONObject;

/**
 * @author monkey
 * @desc 返回数据加密
 * @date 2018/10/25 20:17
 */
@ControllerAdvice
public class EncodeResponseBodyAdvice implements ResponseBodyAdvice {
 
    private final static Logger logger = LoggerFactory.getLogger(EncodeResponseBodyAdvice.class);
    
    @Autowired
    private AcctOperatorLogService acctOperatorLogService;
 
    @Override
    public boolean supports(MethodParameter methodParameter, Class aClass) {
        return true;
    }
 
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
//        boolean encode = false;
//        if (methodParameter.getMethod().isAnnotationPresent(SecurityParameter.class)) {
//            //获取注解配置的包含和去除字段
//            SecurityParameter serializedField = methodParameter.getMethodAnnotation(SecurityParameter.class);
//            //出参是否需要加密
//            encode = serializedField.outEncode();
//        }
        String uri = serverHttpRequest.getURI().toString();
        String token = "";
    	String userId = "";
    	HttpHeaders headers = serverHttpRequest.getHeaders();
//        if (encode) {
//            logger.info("对方法method :【" + methodParameter.getMethod().getName() + "】返回数据进行加密");
//            ObjectMapper objectMapper = new ObjectMapper();
//            try {
//            	String key = null;
//            	if(uri.indexOf("/shiro-api/login")!=-1) {
//            		key = AesEncryptUtils.KEY;
//            	}else if(uri.indexOf("/shiro-api/appLogin")!=-1) {
//            		key = AesEncryptUtils.KEY;
//                }else {
//            		token = serverHttpRequest.getHeaders().get("token").get(0);
//                	String userStr = RedisUtil.get(token);
//                	userId = JSONObject.parseObject(userStr, UserInfo.class).getUserId();
//            		key = RedisUtil.get("AES_KEY:"+token);
//            	}
//                String result = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(body);
//                if (methodParameter.getMethod().isAnnotationPresent(LogParameter.class)) {
//                	String times = headers.getValuesAsList("times").get(0);
//                	this.updateOperatorLog(result, userId, times, uri);
//                }
//                return AesEncryptUtils.encrypt(result, key);
//            } catch (Exception e) {
//                e.printStackTrace();
//                logger.error("对方法method :【" + methodParameter.getMethod().getName() + "】返回数据进行解密出现异常："+e.getMessage());
//                return body;
//            }
//        }else {
        	if (methodParameter.getMethod().isAnnotationPresent(LogParameter.class)) {
	            try {
                    token = serverHttpRequest.getHeaders().get("token").get(0);
                    String userStr = RedisUtil.get(token);
                    userId = JSONObject.parseObject(userStr, SysUserInfo.class).getUserInfoNo();
                    //String times = headers.getValuesAsList("times").get(0);
                    String times = "";
                    this.updateOperatorLog(JSONObject.toJSONString(body), userId, times, uri);
                }catch (Exception e)
                {
                    JSONObject object = new JSONObject();
                    object.put("code",500);
                    object.put("msg","日志失败 没有登录信息");
                    return object;
                }
        	}
        	return body;
//        }
    }
    
    public void updateOperatorLog(String result, String userId, String times, String url){
    	try {
    		//更新日志信息
            AcctOperatorLog acctOperatorLog = new AcctOperatorLog();
            acctOperatorLog.setAolId(times);
            acctOperatorLog.setRequestUrl(url);
            
            //判断是否是登录操作
            if(url.indexOf("/shiro-api/login")!=-1) {
            	String statusStr = result.substring(result.lastIndexOf("status")+11);
            	if("SUCCESS".equals(statusStr.substring(0,statusStr.indexOf("\\")))) {
            		String userStr = result.substring(result.indexOf("auId")+9);
            		userId = userStr.substring(0,userStr.indexOf("\\"));
            	}
            }
            acctOperatorLog.setAuId(userId);
            acctOperatorLog.setResponseResult(result);
            acctOperatorLogService.updateOperator(acctOperatorLog);
    	}catch (Exception e) {
			e.printStackTrace();
		}
    }
}